#include "musiclist.h"
#include "music.h"
#include <QMimeDatabase>
#include <QSqlError>
#include <QSqlQuery>

/**
 * @brief 通过URL列表添加音乐文件到音乐列表中
 * @param music_urls 包含音乐文件路径的QUrl列表
 * @details 该函数遍历提供的URL列表，对每个URL进行MIME类型检查，
 *          只有MIME类型为audio/mpeg、audio/flac或audio/wav的文件才会被添加到音乐列表中。
 *          对于符合条件的音乐文件，会创建对应的musicFile对象并添加到内部的music_list_容器中。
 * @note 支持的音频格式包括MP3、FLAC和WAV格式
 */
void musicList::addMusicByUrl(const QList<QUrl> &music_urls)
{
    // 遍历所有提供的音乐文件URL
    for (auto &e : music_urls)
    {
        // 创建MIME数据库对象用于检测文件类型
        QMimeDatabase mimeDB;
        // 获取文件的MIME类型
        QMimeType mime_type = mimeDB.mimeTypeForFile(e.toLocalFile());
        // 提取MIME类型名称
        QString mime = mime_type.name();
        // 需要将url创建一个musicFile对象，添加到musicList中

        // 检查文件是否为支持的音频格式
        if (mime == "audio/mpeg" || mime == "audio/flac" || mime == "audio/wav")
        {
            // qDebug() << e << ":" << mime;
            // 创建musicFile对象并添加到音乐列表中
            musicFile music_file(e);
            music_list_.emplace_back(music_file);
        }
    }
}

/**
 * @brief 将音乐列表中的所有音乐信息写入数据库
 * @details 该函数遍历音乐列表中的每个musicFile对象，
 *          调用每个对象的insertMusicToDB()方法将音乐信息保存到数据库中。
 *          主要用于程序退出前保存音乐播放列表的状态，包括是否喜欢、是否为历史播放等信息。
 * @note 此操作会更新数据库中所有音乐文件的元数据信息
 */
void musicList::writeToDB()
{
    // 遍历音乐列表中的每个音乐文件对象
    for (auto &music : music_list_)
        // 将音乐信息插入或更新到数据库中
        music.insertMusicToDB();
}

/**
 * @brief 从数据库读取音乐信息并填充音乐列表
 * @details 该函数执行以下操作：
 *          1. 执行SQL查询从musicInfo表中获取所有音乐信息
 *          2. 遍历查询结果，为每条记录创建musicFile对象
 *          3. 设置musicFile对象的各项属性（ID、名称、歌手、专辑、时长、URL、喜欢状态、历史播放状态）
 *          4. 将创建的musicFile对象添加到音乐列表中
 * @note 此函数在程序启动时调用，用于恢复之前保存的音乐列表信息
 */
void musicList::readFromDB()
{
    // 定义SQL查询语句，从musicInfo表中选择所有音乐信息
    QString sql(R"(SELECT musicId, musicName, musicSinger, albumName, duration, musicUrl, isLike, isHistory
                    FROM musicInfo)");
    // 创建SQL查询对象
    QSqlQuery query;
    // 执行SQL查询
    if (!query.exec(sql))
    {
        Debug << "数据库查询失败";
        return;
    }

    // 遍历查询结果
    while (query.next())
    {
        // 创建新的musicFile对象
        musicFile music_file;
        // 设置音乐ID
        music_file.setMusicId(query.value(0).toString());
        // 设置音乐名称
        music_file.setMusicName(query.value(1).toString());
        // 设置音乐歌手
        music_file.setMusicSinger(query.value(2).toString());
        // 设置音乐专辑
        music_file.setMusicAlbum(query.value(3).toString());
        // 设置音乐时长
        music_file.setMusicDuration(query.value(4).toLongLong());
        // 设置音乐URL
        music_file.setMusicUrl(query.value(5).toString());
        // 设置是否喜欢状态
        music_file.setIsLike(query.value(6).toBool());
        // 设置是否为历史播放状态
        music_file.setIsHistory(query.value(7).toBool());

        // 将musicFile对象添加到音乐列表中
        music_list_.push_back(music_file);
    }
}

/**
 * @brief 根据音乐ID查找音乐文件
 * @param music_id 要查找的音乐文件的唯一标识符
 * @return iterator 返回指向找到的音乐文件的迭代器，如果未找到则返回end()迭代器
 * @details 该函数遍历音乐列表，通过比较每个音乐文件的ID与给定ID，
 *          找到匹配的音乐文件并返回指向它的迭代器。
 *          如果没有找到匹配的音乐文件，则返回end()迭代器。
 * @note 查找操作的时间复杂度为O(n)，其中n为音乐列表的大小
 */
iterator musicList::findMusicByMusicId(const QString &music_id)
{
    // 遍历音乐列表
    for (auto it = begin(); it != end(); ++it)
        // 比较当前音乐文件的ID与目标ID
        if (it->getMusicId() == music_id)
            return it;
    // 未找到匹配的音乐文件，返回end()迭代器
    return end();
}

/**
 * @brief 获取指向音乐列表起始位置的迭代器
 * @return iterator 返回指向音乐列表第一个元素的迭代器
 * @details 该函数返回指向音乐列表第一个元素的迭代器，
 *          用于遍历音乐列表的起始位置。
 */
iterator musicList::begin()
{
    return music_list_.begin();
}

/**
 * @brief 获取指向音乐列表结束位置的迭代器
 * @return iterator 返回指向音乐列表最后一个元素之后位置的迭代器
 * @details 该函数返回指向音乐列表结束位置的迭代器，
 *          通常用作遍历音乐列表的结束条件。
 */
iterator musicList::end()
{
    return music_list_.end();
}

